package pr1.cromosoma;

import java.util.ArrayList;
import java.util.List;

public class CromosomaF4 extends Cromosoma<List<Double>> {
	
	public final static double XMAX = 100;
    public final static double XMIN = 0;

    private final int n;
    private final int longX;

    public CromosomaF4(int longX, int n) {
        super(n * longX);
        this.longX = longX;
        this.n = n;
        setAptitud(evalua());
    }

    @Override
    public CromosomaF4 clone() {
        CromosomaF4 clon = new CromosomaF4(longX, n);
        clon.copia(this);
        return clon;
    }

    public void copia(CromosomaF4 otro) {
        assert(this.longX == otro.longX && this.n == otro.n);
        super.copia(otro);
    }

    @Override
	public final double evalua() {
        double sumatorio = 0;
        for(int i = 0; i < n; i++) {
            final double x = getX(i);
            double radicando = Math.sqrt(Math.abs(x));
            sumatorio += - (x * Math.sin(radicando));
        }
        return sumatorio;
	}

	public double getX(int i) {
		return XMIN + (XMAX - XMIN) * bin2dec(i * longX, longX)
				/ (Math.pow(2, longX) - 1);
	}

    @Override
    public List<Double> getFenotipo() {
        ArrayList<Double> fenotipo = new ArrayList<Double>(n);
        for(int i = 0; i < n; i++) {
            fenotipo.add(getX(i));
        }
        return fenotipo;
    }

	public static class Factory implements CromosomaFactory {

		double precision;
		int longCromosoma;
        int n;

        public int getN() {
            return n;
        }

        public void setN(int n) {
            this.n = n;
        }

        public double getPrecision() {
			return precision;
		}

		public void setPrecision(double precision) {
			this.precision = precision;
			longCromosoma = (int) Math.ceil(Math.log(1 + (XMAX - XMIN)
					/ precision)
					/ Math.log(2));
		}

		public Cromosoma generaCromosoma() {
			return new CromosomaF4(longCromosoma, n);
		}
		
		public String toString() {
			return "Cromosoma 4";
		}
	}

}
